package com.mit.service.core.aop;

import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Date;

import org.apache.log4j.Logger;
import org.springframework.aop.AfterReturningAdvice;

import com.mit.common.dto.AbstractDTO;
import com.mit.common.exception.InappropriateDefinitionException;
import com.mit.common.helper.DateHelper;
import com.mit.service.core.dao.ITimestampDAO;

public class CreationTimeAdvice implements AfterReturningAdvice {
	Logger logger = Logger.getLogger(CreationTimeAdvice.class);
	private ITimestampDAO timestampDAO;
	@Override
	public void afterReturning(Object returnValue, Method m, Object[] args,
			Object target) throws Throwable {
		
		AbstractDTO dto = null;
		logger.debug("[Opti-lock] method: " + m.getName());
		
		
		if(returnValue instanceof AbstractDTO)
			dto = (AbstractDTO) returnValue;		
		else{
			logger.info("[Opti-lock] No DTO return. method: " + m.getName());
			return;
		}
		
		Integer id = dto.getId();
		//Throw exception if ID is null in the returned DTO
		if(id == null){
			logger.error("[Opti-Lock] ID should not be null in the creation method, Method name: " + m.getName());
			throw new InappropriateDefinitionException(
					"Generated ID should be set into the returned DTO, use <selectKey> tag. method : "
							+ m.getName());
		}
		
		String className = dto.getClass().getName();
		String tableName = DtoTableMap.getTableName(className);
		// Throw exception if DTO is not mapped
		if(tableName == null){
			logger.error("[Opti-Lock] Table is not mapped in 'dto-table-mapping.xml', DTO: " + className);
			throw new InappropriateDefinitionException(
					"Table is not mapped! Please check dto-table-mapping.xml. DTO: "
							+ className);
		}	
		//TODO for different database, remember using different helper!
		//Date now = DateHelper.toMSSQLDateTime(Calendar.getInstance().getTime());
		Date now = DateHelper.toMYSQLDateTime(Calendar.getInstance().getTime());
		timestampDAO.setCreationTime(now, id, tableName);
		dto.setCreationTime(now);
		dto.setLastUpdatedTime(now);
	}
	public void setTimestampDAO(ITimestampDAO timestampDAO) {
		this.timestampDAO = timestampDAO;
	}
	

}
